package com.hzw.saas.web.shell.config;

import com.hzw.saas.common.security.token.SaasTokenService;
import com.hzw.saas.web.shell.interceptor.HttpSessionIdHandshakeInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration;

import javax.annotation.Resource;

/**
 * <p>
 * websocket握手（handshake）接口
 * </p>
 *
 * @author sonam
 * @since 2021/1/12 17:30
 */
@Slf4j
@Configuration
@EnableWebSocketMessageBroker
@Order(100)
public class SaasWebSocketConfig implements WebSocketMessageBrokerConfigurer {

    private static long HEART_BEAT=5000;

    @Resource
    private SaasTokenService userTokenServices;

    @Resource
    private ChannelInterceptor channelInterceptor;

    @Value(value = "${saas.websocket.message.size:1024000}")
    private Integer messageSize;

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        ThreadPoolTaskScheduler te = new ThreadPoolTaskScheduler();
        te.setPoolSize(1);
        te.setThreadNamePrefix("wss-heartbeat-thread-");
        te.initialize();
        registry.enableSimpleBroker("/webshell") // 服务器发送消息前缀
            .setHeartbeatValue(new long[]{HEART_BEAT,HEART_BEAT}).setTaskScheduler(te);
        registry.setApplicationDestinationPrefixes("/saas"); // @MessageMapping
        registry.setUserDestinationPrefix("/user/"); // 点对点使用
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws/webshell")
            .setAllowedOrigins("*").withSockJS()
            .setInterceptors(httpSessionIdHandshakeInterceptor());
    }

    @Override
    public void configureWebSocketTransport(WebSocketTransportRegistration registry) {
        log.info("Websocket消息大小限制：{}", messageSize);
        registry.setMessageSizeLimit(messageSize) // 设置消息字节数大小
            .setSendBufferSizeLimit(messageSize)// 设置消息缓存大小
            .setSendTimeLimit(10000); // 设置消息发送时间限制毫秒
    }

    @Bean
    public HttpSessionIdHandshakeInterceptor httpSessionIdHandshakeInterceptor() {
        return new HttpSessionIdHandshakeInterceptor(userTokenServices);
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(channelInterceptor);
        registration.taskExecutor().corePoolSize(200);
    }

    @Override
    public void configureClientOutboundChannel(ChannelRegistration registration) {
        registration.taskExecutor().corePoolSize(100);
    }

}
